package work.wiwf.web.cfg.inter;

import java.util.List;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import org.ssssssss.magicapi.core.context.MagicUser;
import org.ssssssss.magicapi.core.exception.MagicLoginException;
import org.ssssssss.magicapi.core.interceptor.Authorization;
import org.ssssssss.magicapi.core.interceptor.AuthorizationInterceptor;
import org.ssssssss.magicapi.core.model.Group;
import org.ssssssss.magicapi.core.model.MagicEntity;
import org.ssssssss.magicapi.core.servlet.MagicHttpServletRequest;

import work.wiwf.web.model.sys.bean.SysUserBean;
import work.wiwf.web.model.sys.bean.vo.SysRoleVo;
import work.wiwf.web.model.sys.bean.vo.SysUserVo;
import work.wiwf.web.model.sys.dao.SysUserMapper;
import work.wiwf.web.model.sys.service.SysTokenService;
import work.wiwf.web.model.sys.service.SysUserService;

/**
 * @author kehui
 */
@Component
public class MagicInterceptor implements AuthorizationInterceptor{

	@Resource
	private HttpServletRequest request;
	@Resource
	private HttpServletResponse response;

	@Resource
	private PasswordEncoder passwordEncoder;
	
	@Resource
	private SysUserMapper userMapper;
	@Resource
	private SysTokenService tokenService;

	@Autowired
	private SysUserService userService;
	
	/**
	 * 是否需要登录
	 *
	 * @return true 需要登录， false 不需要登录
	 */
	@Override
	public boolean requireLogin() {
		return true;
	}

	/**
	 * 根据Token获取User对象
	 *
	 * @param token token值
	 * @return 登录成功后返回MagicUser对象
	 * @throws MagicLoginException 登录失败抛出
	 */
	@Override
	public MagicUser getUserByToken(String token) throws MagicLoginException {
		if (ObjectUtils.isEmpty(token) || "unauthorization".equals(token)) {
			throw new MagicLoginException("token 无效：" + token);
		}

		SysUserVo sysUserVo = tokenService.getTokenUser(token);
		if (ObjectUtils.isEmpty(sysUserVo)) {
			throw new MagicLoginException("token 无效：" + token);
		}

		if (ObjectUtils.isEmpty(sysUserVo)) {
			throw new MagicLoginException("token 无效：" + token);
		}

		return new MagicUser(sysUserVo.getUserId().toString(), sysUserVo.getName(), token);
	}

	/**
	 * 根据用户名，密码登录
	 *
	 * @param username 用户名
	 * @param password 密码
	 * @return 登录成功后返回MagicUser对象
	 * @throws MagicLoginException 登录失败抛出
	 */
	@Override
	public MagicUser login(String username, String password) throws MagicLoginException {
		SysUserVo user = userMapper.getUserInfo(username);

		if (!ObjectUtils.isEmpty(user) && passwordEncoder.matches(password, user.getPassword())) {
			SysUserBean userBean = userService.getUser(username);

			return new MagicUser(user.getUserId().toString(), user.getName(), userBean.getToken());
		}

		throw new MagicLoginException("用户名或密码不正确");
	}

	/**
	 * 退出登录
	 *
	 * @param token token值
	 */
	@Override
	public void logout(String token) {
		tokenService.delTokenUser(token);
	}

	/**
	 * 是否拥有页面按钮的权限
	 *
	 * @param magicUser     登录的用户对象
	 * @param request       HttpServletRequest
	 * @param authorization 鉴权方法
	 * @return true 有权限访问， false 无权限访问
	 */
	@Override
	public boolean allowVisit(MagicUser magicUser, MagicHttpServletRequest request, Authorization authorization) {
		if (isAdmin(magicUser.getToken())) {
			return true;
		}
		return false;
	}

	/**
	 * 是否拥有对该接口的增删改权限
	 *
	 * @param magicUser     登录的用户对象
	 * @param request       HttpServletRequest
	 * @param authorization 鉴权方法
	 * @param entity        接口、函数、数据源信息
	 * @return true 有权限访问， false 无权限访问
	 */
	@Override
	public boolean allowVisit(MagicUser magicUser, MagicHttpServletRequest request, Authorization authorization, MagicEntity entity) {
		return allowVisit(magicUser, request, authorization);
	}


	/**
	 * 是否拥有对该分组的增删改权限
	 *
	 * @param magicUser     登录的用户对象
	 * @param request       HttpServletRequest
	 * @param authorization 鉴权方法
	 * @param group         分组信息
	 * @return true 有权限访问， false 无权限访问
	 */
	@Override
	public boolean allowVisit(MagicUser magicUser, MagicHttpServletRequest request, Authorization authorization, Group group) {
		return allowVisit(magicUser, request, authorization);
	}

	/**
	 * 刷新 token, 重新赋值对象内的token和timeout
	 * @param user
	 * @return
	 */
	@Override
	public void refreshToken(MagicUser user) {

		SysUserVo userVo = userMapper.getUserInfo(user.getUsername());
		// 生成token
		String token = tokenService.getToken();
		// 存储token
		tokenService.addTokenUser(token, userVo, 12 * 60 * 60);
	}

	private Boolean isAdmin(String token) {
		SysUserVo sysUserVo = tokenService.getTokenUser(token);

		List<SysRoleVo> roles = sysUserVo.getRoles();
		for (SysRoleVo sysRoleVo : roles) {
			if ("root".equalsIgnoreCase(sysRoleVo.getRoleCode())) {
				return true;
			}
		}
		return false;
	}
	
}
